/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */

package com.pig4cloud.pigx.wms.controller;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
import com.pig4cloud.pigx.wms.dto.OutDetailForPDABHDTO;
import com.pig4cloud.pigx.wms.dto.OutDetailForPDADTO;
import com.pig4cloud.pigx.wms.dto.SLocationDTO;
import com.pig4cloud.pigx.wms.dto.TPReturnForPDADTO;
import com.pig4cloud.pigx.wms.dto.TiZongListForPDADTO;
import com.pig4cloud.pigx.wms.dto.WGInStorageForPDADTO;
import com.pig4cloud.pigx.wms.entity.B2bTaskRecord;
import com.pig4cloud.pigx.wms.entity.BhTMP;
import com.pig4cloud.pigx.wms.entity.CartInfo;
import com.pig4cloud.pigx.wms.entity.InStorageTp;
import com.pig4cloud.pigx.wms.entity.SCart;
import com.pig4cloud.pigx.wms.entity.SLocation;
import com.pig4cloud.pigx.wms.entity.Sku;
import com.pig4cloud.pigx.wms.entity.SubPackage;
import com.pig4cloud.pigx.wms.entity.TraySku;
import com.pig4cloud.pigx.wms.entity.WcsWmsTrx;
import com.pig4cloud.pigx.wms.service.B2bTaskRecordService;
import com.pig4cloud.pigx.wms.service.BhTMPService;
import com.pig4cloud.pigx.wms.service.CartInfoService;
import com.pig4cloud.pigx.wms.service.InStorageService;
import com.pig4cloud.pigx.wms.service.OutStorageService;
import com.pig4cloud.pigx.wms.service.SLocationService;
import com.pig4cloud.pigx.wms.service.WcsWmsTrxService;
import com.pig4cloud.pigx.wms.vo.OutBHTPForPDAVO;
import com.pig4cloud.pigx.wms.vo.OutTPForPDAVO;
import com.pig4cloud.pigx.wms.vo.PDADSInStorageDetailVO;
import com.pig4cloud.pigx.wms.vo.PDADSInStorageVO;
import com.pig4cloud.pigx.wms.vo.PDADSOutStorageJHVO;
import com.pig4cloud.pigx.wms.vo.PDAWGInStorageDetailVO;
import com.pig4cloud.pigx.wms.vo.PDAWGInStorageVO;
import com.pig4cloud.pigx.wms.vo.PackageListForDSVO;

import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * PDA接口信息
 *
 * @author gaoxin
 * @date 2021-04-25 14:48:32
 */
@Slf4j
@RefreshScope
@RestController
@RequiredArgsConstructor
@RequestMapping("/PDA/" )
@Api(value = "PDA接口信息", tags = "PDA接口信息")
public class PDAInterfaceController {

	private  final InStorageService inStorageService;

	private  final OutStorageService outStorageService;

	private  final SLocationService sLocationService;

	private  final B2bTaskRecordService b2bTaskRecordService;

	private final WcsWmsTrxService wcsWmsTrxService;

	private final BhTMPService bhTMPService;

	private final CartInfoService cartInfoService;

	@Value("${test.peizhi}")
	private String peizhi;

    @ApiOperation(value = "PDA获取电商入库单列表", notes = "PDA获取电商入库单列表")
    @SysLog("PDA获取电商入库单列表" )
    @GetMapping("/pageDSInStorageForPDA")
    public R pageDSInStorageForPDA(Page page, String sort) {

		IPage<PDADSInStorageVO> pdadsInStorageVOIpage = inStorageService.pageDSInStorageForPDA(page,sort);

		log.info(peizhi+"PDA获取电商入库单列表 总数是:"+pdadsInStorageVOIpage.getTotal());

		return R.ok(pdadsInStorageVOIpage);


    }

	@ApiOperation(value = "PDA获取电商入库工作区", notes = "PDA获取电商入库工作区")
	@SysLog("PDA获取电商入库工作区" )
	@GetMapping("/listDSInStorageWorkStationForPDA")
	public R listDSInStorageWorkStationForPDA() {

		List<SLocation> sLocationList = sLocationService.list(Wrappers.<SLocation>query().lambda()
				.eq(SLocation::getAreaId,"5").eq(SLocation::getStatus,"1")
				.eq(SLocation::getIsUsed,"0")
				.eq(SLocation::getLocationStatus,"1").orderByAsc(SLocation::getSOrder));

		return R.ok(sLocationList);

	}

	@ApiOperation(value = "PDA获取外购入库工作区", notes = "PDA获取外购入库工作区")
	@SysLog("PDA获取外购入库工作区" )
	@GetMapping("/listWGInStorageWorkStationForPDA")
	public R listWGInStorageWorkStationForPDA() {

		List<SLocation> sLocationList = sLocationService.list(Wrappers.<SLocation>query().lambda()
				.eq(SLocation::getAreaId,"6").eq(SLocation::getStatus,"1")
				.eq(SLocation::getIsUsed,"0")
				.eq(SLocation::getLocationStatus,"1").orderByAsc(SLocation::getSOrder));

		return R.ok(sLocationList);

	}

	@ApiOperation(value = "PDA通过托盘号获取电商入库单详情", notes = "PDA通过托盘号获取电商入库单详情")
	@SysLog("PDA通过托盘号获取电商入库单详情" )
	@GetMapping("/getDSInStorageDetailByTPForPDA/{uniqueCode}")
	public R getDSInStorageDetailByTPForPDA(@PathVariable String uniqueCode) {

		PDADSInStorageDetailVO pdadsInStorageDetailVO = inStorageService.getDSInStorageDetailByTPForPDA(uniqueCode);

		if(null == pdadsInStorageDetailVO){

			return R.failed("非法托盘或托盘信息不存在...");

		}else{

			return R.ok(pdadsInStorageDetailVO);
		}


	}

	@ApiOperation(value = "PDA提交电商入库请求", notes = "PDA提交电商入库请求")
	@SysLog("PDA提交电商入库请求" )
	@PostMapping("/postDSInStorageDetailForPDA")
	public R postDSInStorageDetailForPDA(String fromLocation,String uniqueCode) throws Exception{

		log.info("收到PDA提交电商入库请求:fromLocation:"+ fromLocation+",托盘编号:"+uniqueCode);

		//校验电商入库合法性
		WcsWmsTrx wcsWmsTrx =
				wcsWmsTrxService.getOne(Wrappers.<WcsWmsTrx>query().lambda()
						.eq(WcsWmsTrx::getTrayNo, uniqueCode).eq(WcsWmsTrx::getFromLocation,fromLocation)
						.eq(WcsWmsTrx::getTrxStatus, "0"));

		if(null != wcsWmsTrx){

			log.error("电商入库处理失败，找到相同的、未完成的提交请求:fromLocation:"+ fromLocation+",托盘编号:"+uniqueCode);

			return R.failed("电商入库处理失败，找到相同的、未完成的提交请求:fromLocation:"+ fromLocation+",托盘编号:"+uniqueCode);

		}

		inStorageService.postDSInStorageDetailForPDA(fromLocation,uniqueCode);

		return R.ok(null,"电商入库处理成功，已经发送WCS指令运送货物...");

	}

	@ApiOperation(value = "PDA外购入库空托补给", notes = "PDA外购入库空托补给")
	@SysLog("PDA外购入库空托补给" )
	@GetMapping("/getWGTPsInStorageTpForPDA")
	public R getWGInStorageTpForPDA() {

		try{

			wcsWmsTrxService.getWGInStorageTpForPDA();
			return R.ok("已经开始处理外购入库空托补给...已经通知wcs运送托盘到外购入库工作区...");

		} catch (Exception e){

			log.error("外购空托补给出现异常..."+e.getMessage());
			e.printStackTrace();
			return R.failed("外购空托补给出现异常...");

		}


	}

	@ApiOperation(value = "PDA获取外购入库单列表", notes = "PDA获取外购入库单列表")
	@SysLog("PDA获取外购入库单列表" )
	@GetMapping("/pageWGInStorageForPDA")
	public R pageWGInStorageForPDA(Page page,String wmsBillNo,String sort) {

		IPage<PDAWGInStorageVO> pdawgInStorageVOIpage = inStorageService.pageWGInStorageForPDA(page,wmsBillNo,sort);

		return R.ok(pdawgInStorageVOIpage);


	}

	@ApiOperation(value = "PDA提交外购入库请求", notes = "PDA提交外购入库请求")
	@SysLog("PDA提交外购入库请求" )
	@PostMapping("/postWGInStorageDetailForPDA")
	public R postWGInStorageDetailForPDA(WGInStorageForPDADTO wgInStorageForPDADTO) throws Exception{

		log.info("收到PDA提交外购入库请求:"+ JSONUtil.toJsonStr(wgInStorageForPDADTO));

		inStorageService.postWGInStorageDetailForPDA(wgInStorageForPDADTO);

		return R.ok(null,"外购入库已成功处理,已经通知wcs运送货物到指定地点...");

	}

	@ApiOperation(value = "PDA获取外购入库单已提交列表", notes = "PDA获取外购入库单已提交列表")
	@SysLog("PDA获取外购入库单已提交列表" )
	@GetMapping("/listDSInStorageForPDA/{wmsBillNo}/{inStorageItemId}")
	public R listWGInStorageDetailForPDA(@PathVariable String wmsBillNo,@PathVariable String inStorageItemId) {

		List<PDAWGInStorageDetailVO> pdawgInStorageDetailVOIPage =
				inStorageService.listWGInStorageDetailForPDA(wmsBillNo,inStorageItemId);

		return R.ok(pdawgInStorageDetailVOIPage);
	}

	@ApiOperation(value = "PDA获取外购入库单详情", notes = "PDA获取外购入库单详情")
	@SysLog("PDA获取外购入库单详情" )
	@GetMapping("/getWGInStorageDetailForPDA/{wmsBillNo}/{inStorageItemId}")
	public R getDSInStorageDetailForPDA(@PathVariable String wmsBillNo,@PathVariable String inStorageItemId) {

    	log.info("收到PDA获取外购入库单详情请求:wmsBillNo:"+wmsBillNo+"行项目编号:"+inStorageItemId);

		PDADSInStorageDetailVO pdadsInStorageDetailVO = inStorageService.getWGInStorageDetailForPDA(wmsBillNo,inStorageItemId);

		return R.ok(pdadsInStorageDetailVO);

	}

	@ApiOperation(value = "PDA获取产线B2B已完成的任务列表", notes = "PDA获取产线B2B已完成的任务列表")
	@SysLog("PDA获取产线B2B已完成的任务列表" )
	@GetMapping("/listB2BTaskRecord")
	public R pageDSInStorageForPDA() {

		List<B2bTaskRecord> b2bTaskRecords =
				b2bTaskRecordService.list(Wrappers.<B2bTaskRecord>query().lambda().eq(B2bTaskRecord::getOperator,SecurityUtils.getUser().getUsername()));

		return R.ok(b2bTaskRecords);


	}

	@ApiOperation(value = "PDA获取出库托盘详情", notes = "PDA获取出库托盘详情")
	@SysLog("PDA获取出库托盘详情" )
	@GetMapping("/getOutTPDetailForB2B/{uniqueCode}")
	public R listDSInStorageWorkStationForPDA(@PathVariable String uniqueCode) {

        //校验合法托盘
//		TraySku traySku = traySkuService.getById(uniqueCode);

		OutTPForPDAVO outTPForPDAVO = outStorageService.getOutTPDetailForPDA(uniqueCode);

		return R.ok(outTPForPDAVO);

	}

	@ApiOperation(value = "PDA提交B2B出库托盘", notes = "PDA提交B2B出库托盘")
	@SysLog("PDA提交B2B出库托盘" )
	@PostMapping("/submitB2BOutDetail")
	public R submitOutDetail(OutDetailForPDADTO outDetailForPDADTO) {

		log.info("收到PDA提交B2B出库托盘请求:"+ JSONUtil.toJsonStr(outDetailForPDADTO));

		outStorageService.submitOutDetail(outDetailForPDADTO);

		return R.ok("产线出库托盘已提交成功");

	}

	@ApiOperation(value = "PDA提交出库托盘返库", notes = "PDA提交出库托盘返库")
	@SysLog("PDA提交出库托盘返库" )
	@PostMapping("/tpReturnForPDA")
	public R tpReturn(TPReturnForPDADTO tpReturnForPDADTO) {

		outStorageService.tpReturnForPDA(tpReturnForPDADTO);

		return R.ok("托盘剩余货物正在重新入库...已通知wcs运送货物");

	}

	@ApiOperation(value = "PDA提交出库空托盘返回叠盘机", notes = "PDA提交出库空托盘返回叠盘机")
	@SysLog("PDA提交出库空托盘返回叠盘机" )
	@PostMapping("/submitTPRETURN")
	public R emptyTPReturn(String fromLocation,String TPNO) {

		outStorageService.emptyTPReturnForPDA(fromLocation,TPNO);

		return R.ok("托盘正在返回叠盘机..");

	}

	@ApiOperation(value = "PDA获取电商波次单列表", notes = "PDA获取电商波次单列表")
	@SysLog("PDA获取电商波次单列表" )
	@GetMapping("/getPackageListForDS")
	public R getPackageListForDS() {

		List<PackageListForDSVO> packageListForDSVOList = outStorageService.getPackageListForDS();

		return R.ok(packageListForDSVOList);

	}

	@ApiOperation(value = "PDA领取电商出库任务", notes = "PDA领取电商出库任务")
	@SysLog("PDA领取电商出库任务" )
	@GetMapping("/getPackageTaskForDS")
	public R getPackageTaskForDS() {

		boolean success = outStorageService.getPackageTaskForDS();

		if(success){
			return  R.ok("领取电商任务成功");
		}else{
			return R.failed("领取电商任务失败");
		}
	}

	@ApiOperation(value = "PDA获取电商出库任务列表", notes = "PDA获取电商出库任务列表")
	@SysLog("PDA获取电商出库任务列表" )
	@GetMapping("/listPackageTaskForDS")
	public R listPackageTaskForDS() {

			return  R.ok(outStorageService.listPackageTaskForDS());
	}

	@ApiOperation(value = "PDA获取电商出库任务详情", notes = "PDA获取电商出库任务详情")
	@SysLog("PDA获取电商出库任务详情" )
	@GetMapping("/listPackageTaskDetailForDS/{wmsBillNo}")
	public R listPackageTaskDetailForDS(@PathVariable String wmsBillNo) {

		return  R.ok(outStorageService.listPackageTaskDetailForDS(wmsBillNo));
	}

	@ApiOperation(value = "PDA提交电商出库任务", notes = "PDA提交电商出库任务")
	@SysLog("PDA提交电商出库任务" )
	@PostMapping("/submitPackageTaskDetailForDS")
	public R submitPackageTaskDetailForDS(String wmsBillNo) {

		boolean success = outStorageService.submitPackageTaskDetailForDS(wmsBillNo);

		if(success){
			return  R.ok();
		}else{
			return  R.failed();
		}

	}

	@ApiOperation(value = "PDA获取电商补货列表", notes = "PDA获取电商补货列表")
	@SysLog("PDA获取电商补货列表" )
	@GetMapping("/getBHListForDS")
	public R getBHListForDS() {


		List<BhTMP> bhTMPS = bhTMPService.list(Wrappers.<BhTMP>query().lambda().eq(BhTMP::getDel,"0"));

			return R.ok(bhTMPS);

	}

	@ApiOperation(value = "PDA获取出库提总补货托盘详情", notes = "PDA获取出库提总补货托盘详情")
	@SysLog("PDA获取出库补货托盘详情" )
	@GetMapping("/getOutBHTPDetailForDS/{subPackageNo}/{uniqueCode}")
	public R getOutBHTPDetailForDS(@PathVariable String subPackageNo, @PathVariable String uniqueCode) {

		OutBHTPForPDAVO outBHTPForPDAVO = outStorageService.getOutBHTPDetailForPDA(subPackageNo,uniqueCode);

		return R.ok(outBHTPForPDAVO);

	}

	@ApiOperation(value = "PDA提交DS补货出库托盘", notes = "PDA提交DS补货出库托盘")
	@SysLog("PDA提交DS补货出库托盘" )
	@PostMapping("/submitBHOutDetail")
	public R submitBHOutDetail(OutDetailForPDABHDTO outBHDetailForPDADTO) {

		outStorageService.submitBHOutDetail(outBHDetailForPDADTO);

		return R.ok("电商提总补货已提交");

	}

	@ApiOperation(value = "PDA获取电商L区收货位置", notes = "PDA获取电商L区收货位置")
	@SysLog("PDA获取电商L区收货位置" )
	@GetMapping("/listDSLOutStorageWorkStationForPDA")
	public R listDSLOutStorageWorkStationForPDA() {

		List<SLocation> sLocationList = sLocationService.list(Wrappers.<SLocation>query().lambda()
				.eq(SLocation::getAreaId,"10").eq(SLocation::getStatus,"1")
				.eq(SLocation::getIsUsed,"0")
				.eq(SLocation::getLocationStatus,"1").orderByAsc(SLocation::getSOrder));

		return R.ok(sLocationList);

	}

	@ApiOperation(value = "PDA获取提总波次列表", notes = "PDA获取提总波次列表")
	@SysLog("PDA获取提总波次列表" )
	@GetMapping("/listDSSubPackageForPDA")
	public R listDSSubPackageForPDA() {

		List<SubPackage> subPackages = outStorageService.listSubPackageForDS();

		return R.ok(subPackages);

	}

	@ApiOperation(value = "PDA获取提总列表", notes = "PDA获取提总列表")
	@SysLog("PDA获取提总列表" )
	@GetMapping("/listTZDSSubPackageForPDA/{subPackageNo}")
	public R listTZDSSubPackageForPDA(@PathVariable String subPackageNo) {

		List<TiZongListForPDADTO> subPackages = outStorageService.listTZDSSubPackageForPDA(subPackageNo);

		return R.ok(subPackages);

	}

	@ApiOperation(value = "PDA获取提总库位列表", notes = "PDA获取提总库位列表")
	@SysLog("PDA获取提总库位列表" )
	@GetMapping("/listTZDSLocationForPDA")
	public R listTZDSLocationForPDA() {

		List<SLocationDTO> sLocationDTOS = new ArrayList<>();

			List<SLocation>	sLocationList = sLocationService.list(Wrappers.<SLocation>query().lambda()
					.eq(SLocation::getAreaId,"9").eq(SLocation::getStatus,"1")
					.eq(SLocation::getIsUsed,"0")
					.eq(SLocation::getLocationStatus,"1").orderByAsc(SLocation::getSOrder));

			for(SLocation sLocation : sLocationList){

				SLocationDTO sLocationDTO = new SLocationDTO();
				sLocationDTO.setAreaId("9");
				sLocationDTO.setHuozId(sLocation.getHuozId());
				sLocationDTO.setSLocationNo(sLocation.getSLocationNo());
				sLocationDTO.setStatus(sLocation.getStatus());
				sLocationDTOS.add(sLocationDTO);
			}

		return R.ok(sLocationDTOS);

	}

	@ApiOperation(value = "PDA获取当前激活子波次相关的拣货小车列表", notes = "PDA获取当前激活子波次相关的拣货小车列表")
	@SysLog("PDA获取当前激活子波次相关的拣货小车列表" )
	@GetMapping("/listCartsSubPackageDSForPDA")
	public R listCartsSubPackageDSForPDA() {

		List<SCart> sCarts = outStorageService.listCartsSubPackageDSForPDA();

		return R.ok(sCarts);

	}

	@ApiOperation(value = "PDA获取拣货小车详情列表", notes = "PDA获取拣货小车详情列表")
	@SysLog("PDA获取拣货小车详情列表" )
	@GetMapping("/listCartsDetailForPDA/{cartId}")
	public R listCartsDetailForPDA(@PathVariable String cartId) {

		List<PDADSOutStorageJHVO> pdadsOutStorageJHVOS = outStorageService.listCartsDetailForPDA(cartId);

		return R.ok(pdadsOutStorageJHVOS);

	}

	@ApiOperation(value = "PDA获取当子前波次sku列表", notes = "PDA获取当子前波次sku列表")
	@SysLog("PDA获取当子前波次sku列表" )
	@GetMapping("/listCartSKUsForPDA/{cartId}")
	public R listCartSKUsForPDA(@PathVariable String cartId) {

		List<Sku> skus = outStorageService.listCartSKUsForPDA(cartId);

		return R.ok(skus);

	}

	@ApiOperation(value = "PDA提交电商拣货任务", notes = "PDA提交电商拣货任务")
	@SysLog("PDA提交电商拣货任务" )
	@PostMapping("/submitJHTaskForDS")
	public R submitJHTaskForDS(String cartInfoId) {

		boolean success = outStorageService.submitJHTaskForDS(cartInfoId);

		if(success){
			return  R.ok();
		}else{
			return  R.failed();
		}

	}

	@ApiOperation(value = "PDA提总补货", notes = "PDA提总补货")
	@SysLog("PDA提总补货" )
	@GetMapping("/getNextTZForDS/{packageNo}")
	public R getNextTZForDS(@PathVariable String packageNo) {

		boolean success = outStorageService.getNextTZForDS(packageNo);

		if(success){
			return  R.ok(null,"提总成功，正在通知wcs运送货物");
		}else{
			return  R.failed("提总补货失败");
		}

	}

}
